<script lang="ts" setup>
import type { OpenCallbackMeta } from '@/components/JumpLinkModal/type'
import { EIntroduction01MediaType, type Introduction01Item } from '@/api/designer/model'
import AddButton from '@/components/AddButton/AddButton.vue'
import BlockOpts from '@/components/CompAttr/BlockOpts.vue'
import CompStyle from '@/components/CompAttr/CompStyle.vue'
import ContainerMask from '@/components/CompAttr/ContainerMask.vue'
import Condition from '@/components/Condition/Condition.vue'
import { type Introduction01ComponentMeta, JumpType, JumpTypeMap } from '@/definitions/type'
import { useCompRefs } from '@/hooks/useCompRefs'
import { useCompStyle } from '@/hooks/useCompStyle'
import { useUpload } from '@/hooks/useUpload'
import { removeItem, sortItem } from '@/utils/helper'
import { buildShortUUID } from '@/utils/uuid'
import { Button, Input, Popconfirm, Radio, RadioButton, RadioGroup, Space, Textarea } from 'ant-design-vue'
import { ref } from 'vue'

defineOptions({
  name: 'Introduction01Attr',
  inheritAttrs: true,
})
const { VideoPreviewModalRef } = useCompRefs()
const { activeRender } = useCompStyle<Introduction01ComponentMeta>()
const currentUploadItem = ref<Nullable<Introduction01Item>>(null)
const uploadOpts: Parameters<typeof useUpload>['0'] = {
  successHandler({ url }) {
    if (activeRender.value && activeRender.value.config.items) {
      if (activeRender.value.config.items.length > 0) {
        if (currentUploadItem.value) {
          const index = activeRender.value.config.items.findIndex(l => l.id === currentUploadItem.value!.id)
          if (~index) {
            activeRender.value.config.items[index].url = url
          }
          currentUploadItem.value = null
        }
        else {
          activeRender.value.config.items.push(createUploadItem(url))
        }
      }
      else {
        activeRender.value.config.items.push(createUploadItem(url))
      }
    }
  },
  finallyHandler() {
    currentUploadItem.value = null
  },
}
// 配图为图片/轮播图类型-上传图片/轮播图
const { uploadAction: uploadImage } = useUpload(uploadOpts)
// 配图为视频类型-上传视频
const { uploadAction: uploadVideo } = useUpload({
  ...uploadOpts,
  type: 'video',
})
// 配图为视频类型-上传视频封面
const { uploadAction: uploadVideoPoster } = useUpload({
  successHandler({ url }) {
    if (activeRender.value && activeRender.value.config.items) {
      if (activeRender.value.config.items.length > 0) {
        if (currentUploadItem.value) {
          const index = activeRender.value.config.items.findIndex(l => l.id === currentUploadItem.value!.id)
          if (~index) {
            activeRender.value.config.items[index].coverOrName = url
          }
          currentUploadItem.value = null
        }
        else {
          activeRender.value.config.items.push(createUploadItem(url, true))
        }
      }
      else {
        activeRender.value.config.items.push(createUploadItem(url, true))
      }
    }
  },
  finallyHandler() {
    currentUploadItem.value = null
  },
})
function tapModifyUploadItem(item: Introduction01Item) {
  currentUploadItem.value = item
  uploadImage()
}
function tapModifyUploadVideo(item: Introduction01Item) {
  currentUploadItem.value = item
  uploadVideo()
}
function tapModifyVideoPoster(item: Introduction01Item) {
  currentUploadItem.value = item
  uploadVideoPoster()
}
function handlePreviewVideo(item: Introduction01Item) {
  if (VideoPreviewModalRef.value) {
    VideoPreviewModalRef.value.open({
      url: item.url,
    })
  }
}
function createUploadItem(url: string, urlAsCover = false): Introduction01Item {
  return {
    id: buildShortUUID(),
    url: urlAsCover ? '' : url,
    coverOrName: urlAsCover ? url : '',
  }
}
function handleRemoveItem(item: Introduction01Item) {
  if (!activeRender.value)
    return
  removeItem(activeRender.value.config.items!, l => l.id === item.id)
}
function handleSort(item: Introduction01Item, type: 'up' | 'down') {
  sortItem(activeRender.value!.config.items!, l => l.id === item.id, type)
}
function handleChangeMediaType() {
  if (activeRender.value) {
    activeRender.value.config.items!.length = 0
  }
}
const { JumpLinkModalRef } = useCompRefs()
function handleChooseJumpLink() {
  if (JumpLinkModalRef.value) {
    const { jumpType, jumpTitle, jumpUrl, jumpValue } = activeRender.value!.config
    JumpLinkModalRef.value.open({
      jumpType,
      jumpTitle,
      jumpUrl,
      jumpValue,
    }, chooseJumpCallback)
  }
}
function handleRemoveItemJumpLink() {
  activeRender.value!.config.jumpType = JumpType.None as any
  activeRender.value!.config.jumpTitle = ''
  activeRender.value!.config.jumpUrl = ''
  activeRender.value!.config.jumpValue = ''
}
function chooseJumpCallback(meta: OpenCallbackMeta) {
  if (activeRender.value && meta.applied) {
    activeRender.value.config = {
      ...activeRender.value.config,
      ...meta.value,
    }
  }
}
</script>

<template>
  <div v-if="activeRender">
    <div class="setting-block">
      <div class="field-title">
        组件模板
      </div>
      <RadioGroup button-style="solid" :value="activeRender.config.template">
        <RadioButton v-for="item of activeRender.config.templateOptions" :key="item.value" :value="item.value">
          {{ item.label }}
        </RadioButton>
      </RadioGroup>
    </div>
    <div class="setting-block">
      <div class="field-title">
        组件内容
      </div>
      <Space :size="20" direction="vertical" style="width: 100%;">
        <div class="inline-control">
          <div class="inline-control-label">
            配图类型
          </div>
          <div class="inline-control-block">
            <RadioGroup v-model:value="activeRender.config.mediaType" @change="handleChangeMediaType">
              <Radio v-for="item of activeRender.config.mediaTypeOptions" :key="item.value" :value="item.value">
                {{ item.label }}
              </Radio>
            </RadioGroup>
          </div>
        </div>
        <!-- 图片类型 -->
        <Condition v-if="activeRender.config.mediaType === EIntroduction01MediaType.图片" :arrow-left="86">
          <template v-if="activeRender.config.items && activeRender.config.items.length > 0">
            <div v-for="item of activeRender.config.items" :key="item.id" class="flex flex-row gap-2 items-center bg-white p-2 relative">
              <!-- 左侧图片 -->
              <div class="relative flex-none w-100px h-74px rounded overflow-hidden cursor-pointer image-wrap">
                <img :src="item.url" :width="100" :height="74" class="block w-100px h-74px">
                <ContainerMask class="image-wrap-mask" @click="tapModifyUploadItem(item)" />
              </div>
              <!-- 右侧属性 -->
              <div class="flex-1 ">
                <Input v-model:value="item.coverOrName" placeholder="请输入配图文字(选填)" />
                <div class="text-xs text-second-app mt-5">
                  建议图片宽度750px
                </div>
              </div>
              <!-- 删除图标 -->
              <Popconfirm
                ok-text="确定" cancel-text="取消" title="确定要删除该项吗?" placement="left"
                @confirm="handleRemoveItem(item)"
              >
                <i class="i-ant-design:close-circle-filled w-4 h-4 cursor-pointer absolute -top-2 -right-2" />
              </Popconfirm>
            </div>
          </template>
          <AddButton v-else size="middle" style="margin-top: 0;" @click="uploadImage">
            添加图片
          </AddButton>
        </Condition>
        <!-- 视频类型 -->
        <Condition v-if="activeRender.config.mediaType === EIntroduction01MediaType.视频" :arrow-left="154">
          <template v-if="activeRender.config.items && activeRender.config.items.length > 0">
            <div v-for="item of activeRender.config.items" :key="item.id" class="bg-white p-2 relative">
              <div class="flex flex-row gap-2 items-start">
                <!-- 左侧图片 -->
                <div class="relative flex-none w-100px h-74px rounded overflow-hidden cursor-pointer video-image-wrap">
                  <video :src="item.url" :width="100" :height="74" preload="metadata" class="block w-100px h-74px object-contain" />
                  <!-- 视频播放按钮 -->
                  <img src="/images/vidio-play-btn.png" :width="33" :height="33" class="video-play-btn">
                  <ContainerMask class="image-wrap-mask" @click="tapModifyUploadVideo(item)" />
                </div>
                <!-- 右侧属性 -->
                <div class="flex-1 ">
                  <Button type="primary" ghost size="small" style="font-size: 12px;" @click="handlePreviewVideo(item)">
                    预览
                  </Button>
                  <div class="text-xs text-second-app mt-5">
                    建议视频大小50MB
                  </div>
                </div>
              </div>
              <div class="text-sm text-second-render mt-14px mb-2">
                视频封面
              </div>
              <div class="flex flex-row gap-2 items-start">
                <!-- 左侧图片 -->
                <div class="relative flex-none w-100px h-74px rounded overflow-hidden cursor-pointer video-poster-wrap" :class="item.coverOrName ? 'has-poster' : ''" @click="tapModifyVideoPoster(item)">
                  <!-- 视频封面 -->
                  <img v-if="item.coverOrName" :src="item.coverOrName" :width="100" :height="74" class="block w-100px h-74px object-cover">
                  <img v-else src="/images/upload-placeholder.png" :width="32" :height="32" class="video-poster-placeholder">
                  <ContainerMask class="image-wrap-mask" />
                </div>
                <!-- 右侧属性 -->
                <div class="flex-1 flex flex-col self-end">
                  <div class="text-xs text-second-app">
                    建议图片宽度750px
                  </div>
                </div>
              </div>
            </div>
          </template>
          <AddButton v-else size="middle" style="margin-top: 0;" @click="uploadVideo">
            添加视频
          </AddButton>
        </Condition>
        <!-- 轮播类型 -->
        <Condition v-if="activeRender.config.mediaType === EIntroduction01MediaType.轮播" :arrow-left="222">
          <template v-if="activeRender.config.items && activeRender.config.items.length > 0">
            <div v-for="(item, index) in activeRender.config.items" :key="item.id" class="relative w-full pr-8 mb-[14px]">
              <div class="flex flex-row gap-2 items-center bg-white p-2 relative">
                <!-- 左侧图片 -->
                <div class="relative flex-none w-100px h-74px rounded overflow-hidden cursor-pointer image-wrap">
                  <img :src="item.url" :width="100" :height="74" class="block w-100px h-74px">
                  <ContainerMask class="image-wrap-mask" @click="tapModifyUploadItem(item)" />
                </div>
                <!-- 右侧属性 -->
                <div class="flex-1 ">
                  <Input v-model:value="item.coverOrName" placeholder="请输入配图文字(选填)" />
                  <div class="text-xs text-second-app mt-5">
                    建议图片宽度750px
                  </div>
                </div>
              </div>
              <BlockOpts
                :item="item" :disabled-up="index === 0" :disabled-down="index === activeRender.config.items.length - 1"
                @remove="handleRemoveItem"
                @sort="handleSort"
              />
            </div>
          </template>
          <AddButton size="middle" style="margin-top: 0;" @click="uploadImage">
            添加轮播图
          </AddButton>
        </Condition>
        <div class="field-control">
          <div class="field-label">
            图文标题
          </div>
          <Input
            v-model:value="activeRender.config.title" placeholder="请输入标题"
            :min-length="activeRender.config.titleRules?.min" :max-length="activeRender.config.titleRules?.max"
            :required="activeRender.config.titleRules?.required"
          />
        </div>
        <div class="field-control">
          <div class="field-label">
            图文内容
          </div>
          <Textarea
            v-model:value="activeRender.config.description" placeholder="请输入图文内容"
            :min-length="activeRender.config.descriptionRules?.min"
            :max-length="activeRender.config.descriptionRules?.max"
            :required="activeRender.config.descriptionRules?.required" :auto-size="{ minRows: 16 }"
          />
        </div>
        <div class="field-control" style="flex-direction: row; gap: 24px;">
          <div class="field-label">
            图文链接
          </div>
          <div class="box-border flex-1">
            <!-- CASE: 未选择链接 -->
            <div
              v-if="(activeRender.config.jumpType as any) === JumpType.None"
              class="cursor-pointer text-primary-app text-sm flex items-center" @click="handleChooseJumpLink()"
            >
              选择跳转到的页面<i class="i-ant-design:right-outlined w-4 h-4 ml-1" />
            </div>
            <!-- CASE: 已选择链接 -->
            <div v-else class="flex-1 flex flex-row items-center">
              <div class="flex-1 truncate text-main-app text-sm">
                {{ JumpTypeMap.get(activeRender.config.jumpType as any) }} | {{ activeRender.config.jumpTitle }}
              </div>
              <i
                class="i-ant-design:edit-outlined w-4 h-4 cursor-pointer text-primary-app flex-none"
                @click="handleChooseJumpLink()"
              />
              <Popconfirm
                ok-text="确定" cancel-text="取消" title="确定要删除该链接吗?" placement="left"
                @confirm="handleRemoveItemJumpLink()"
              >
                <i class="i-ant-design:delete-outlined w-4 h-4 cursor-pointer text-primary-app flex-none" />
              </Popconfirm>
            </div>
          </div>
        </div>
        <div class="field-control">
          <div class="field-label">
            按钮文案
          </div>
          <Input
            v-model:value="activeRender.config.buttonText" placeholder="请输入按钮文案"
            :minlength="activeRender.config.buttonTextRules?.min" :max-length="activeRender.config.buttonTextRules?.max"
            :required="activeRender.config.buttonTextRules?.required"
          />
        </div>
      </Space>
    </div>
    <CompStyle />
  </div>
</template>

<style lang="less" scoped>
.inline-control {
  @apply flex flex-row gap-8 items-start;

  .inline-control-label {
    color: var(--app-text-color-second);
    @apply text-sm flex-none;
  }

  .inline-control-block {
    color: var(--app-text-color-main);
    @apply text-sm;
  }
}
</style>

<style lang="less" scoped>
.setting-block {
  @apply mb-6;
}

.field-title {
  color: var(--app-text-color-main);
  @apply font-bold text-sm mb-14px;
}

.field-control {
  color: var(--app-text-color-main);
  @apply flex flex-col gap-2;

  .field-label {
    color: var(--app-text-color-second);
    @apply text-sm;
  }
}
.image-wrap:hover .image-wrap-mask {
  opacity: 1;
}
.video-image-wrap:hover .image-wrap-mask {
  opacity: 1;
}
.video-poster-wrap {
  border-radius: 4px;
  border: 1px solid #DDD;
  background: #F5F7FA;
}
.video-poster-wrap.has-poster:hover .image-wrap-mask {
  opacity: 1;
}
.video-play-btn {
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  @apply block w-33px h-33px object-contain absolute;
}
.video-poster-placeholder {
  margin: 20px auto;
  @apply block w-32px h-32px;
}
</style>
